<template>
	<view class="content">
		<view class="header">
			<up-search
				:clearabled="true"
				v-model="params.keywords"
				searchIcon="arrow-left"
				@custom="clickSearch()"
				@clickIcon="goIndex()"
				@clear="resetparams()"
				:actionText="t('index.searchBtn')"></up-search>
		</view>
		<view view class="content" v-if="deviceList.length">
			<DeviceList
				:lastDeviceList="lastDeviceList"
				:toppedDevices="toppedDevices"
				:isTwo="true"
				@updateTopList="updateTopList"
				@cancelAfter="cancelAfter"
				@updateDevicesTop="updateDeviceTop" />
			<view class="no-more" v-if="isLoadComplete">
				{{ t("noMore") }}
			</view>
		</view>
		<view class="empty-box" v-if="isNoData">
			<up-avatar
				shape="square"
				size="180"
				src="/static/image/index/noData.png"></up-avatar>
			<view class="empty-title">{{ t("index.noSearchDevice") }}</view>
			<view class="empty-tip">{{ t("index.noSearchDeviceInfo") }}</view>
		</view>
	</view>
</template>
<script setup lang="ts">
import { getCurrentInstance, ref, reactive, computed, onMounted } from "vue";
import DeviceList from "../components/deviceList.vue";
import { onReachBottom } from "@dcloudio/uni-app";
import type * as type from "../type";
import { onLoad } from "@dcloudio/uni-app";
import { useI18n } from "vue-i18n";
const { locale, t } = useI18n();
import { getBoundVcus } from "@/service/index";
const isLoadComplete = ref(false);
const deviceList = ref<type.Device[]>([]);
const toppedDevices = ref<string[]>([]);
const isLoading = ref(false);
const topDeviceList = ref<type.Device[]>([]);
const instance: any = getCurrentInstance();
const tokenStore = useUniversalStorage("token", "");
const isNoData = ref(false);
const params = reactive<type.searchParams>({
	page: 1,
	size: 20,
	keywords: "",
});
const goIndex = () => {
	uni.switchTab({
		url: "/pages/index/index",
	});
};
const showLoading = () => {
	uni.showLoading({
		title: t("loading"),
		mask: true,
	});
};
// 重置查询
const resetparams = () => {
	(params.page = 1), (params.size = 20), (deviceList.value = []);
	isLoadComplete.value = false;
	isNoData.value = false;
};
const lastDeviceList = computed<type.Device[]>(() => {
	if (!deviceList.value?.length) return [];
	const sorted = [...deviceList.value];
	// 无置顶设备时直接返回
	if (!toppedDevices.value) return sorted;
	const deviceMap = new Map<string, type.Device>();
	sorted.forEach((device) => {
		deviceMap.set(device.device_sn, device);
	});
	const topItems: type.Device[] = [];
	const snOrder = toppedDevices.value;

	snOrder.forEach((sn) => {
		const device = deviceMap.get(sn);
		if (device) {
			topItems.push(device);
			deviceMap.delete(sn); // 从map中移除已处理项
		}
	});
	// 剩余未置顶设备
	const normalItems = Array.from(deviceMap.values());
	return [...topItems, ...normalItems];
});
const updateTopList = (deviceSn: string) => {
	const deviceIndex = deviceList.value.findIndex(
		(dev) => dev.device_sn === deviceSn
	);
	if (deviceIndex > -1) {
		const newDeviceList = [...deviceList.value];
		const [topDevice] = newDeviceList.splice(deviceIndex, 1);
		deviceList.value = newDeviceList;
		topDeviceList.value = [topDevice, ...topDeviceList.value];
	}
};
const updateDeviceTop = (newToppedDevices: string) => {
	toppedDevices.value = newToppedDevices.split(",");
};
// 处理置顶设备
const handleTopDevices = (data: type.TopDeviceData) => {
	if (!data.top_devices || data.top_devices.length === 0) return;
	// 检查数据是否变化
	const isDataChanged =
		JSON.stringify(data.top_devices) !==
		JSON.stringify(topDeviceList.value);
	if (!isDataChanged) return;
	// 更新置顶设备索引
	toppedDevices.value = data.top_index ? data.top_index.split(",") : [];

	if (data.top_index) {
		// 按指定顺序排序
		const deviceMap = data.top_devices.reduce((map, device) => {
			map[device.device_sn] = device;
			return map;
		}, {} as Record<string, type.Device>);
		topDeviceList.value = toppedDevices.value
			.map((sn) => deviceMap[sn])
			.filter(Boolean);
	} else {
		// 无排序索引时直接使用原始数据
		topDeviceList.value = data.top_devices;
	}
};
const cancelAfter = (deviceSn: string) => {
	const deviceIndex = topDeviceList.value.findIndex(
		(dev) => dev.device_sn === deviceSn
	);
	const device = deviceIndex > -1 ? topDeviceList.value[deviceIndex] : null;
	if (deviceIndex > -1 && device) {
		topDeviceList.value.splice(deviceIndex, 1);
		deviceList.value.push(device);
	}
};
// 检查数据是否为空
const checkEmptyData = (data: { devices?: any[] }) => {
	const isEmpty = !data?.devices?.length;

	isLoadComplete.value = true;
	isNoData.value = isEmpty && !deviceList.value.length;

	if (isEmpty) return true;
	return false;
};
const handleDevicesData = (data: type.Device[]) => {
	if (checkEmptyData(data)) return;
	handleTopDevices(data);
	if (params.page === 1) {
		deviceList.value = [];
	}
	const filteredDevices = data.devices.filter(
		(device: type.Device[]) =>
			!toppedDevices.value.includes(device.device_sn)
	);
	deviceList.value = [...deviceList.value, ...filteredDevices];
};
const getDeviceList = async () => {
	if (params.page === 1) {
		showLoading();
	}
	try {
		uni.hideLoading();
		isLoading.value = true;
		const { data } = await getBoundVcus(params);
		if (data && !data.code) {
			handleDevicesData(data.data || []);
		} else {
			if (tokenStore.value) {
				instance.proxy.$message(
					data?.msg || t("request.failed"),
					"warning"
				);
			}
		}
	} catch (error) {
		instance.proxy.$message(t("device.list.failed"), "error");
	} finally {
		uni.hideLoading();
		isLoading.value = false;
	}
};
// 上拉加载更多
onReachBottom(async () => {
	if (isLoading.value || isLoadComplete.value) return;
	try {
		params.page += 1;
		getDeviceList();
	} finally {
		isLoading.value = false;
	}
});
const clickSearch = () => {
	resetparams();
	getDeviceList();
};
onLoad((options: any) => {
	if (options.toppedDevices) {
		updateDeviceTop(options.toppedDevices);
	}
});
const topHeight = ref("0");
onMounted(() => {
	// 获取状态栏高度
	// #ifdef APP-PLUS
	const statusBarHeight = ref(0);
	const systemInfo = uni.getSystemInfoSync();
	statusBarHeight.value = systemInfo.statusBarHeight || 0;
	topHeight.value = statusBarHeight.value + "px";
	// #endif
});
</script>

<style lang="scss" scoped>
.content {
	height: 100vh;
	background: #fff;
}
.content {
	// #ifdef APP-PLUS
	padding: 60rpx 30rpx 60rpx;
	// #endif
	// #ifdef H5
	padding: 40rpx 20rpx 60rpx;
	// #endif
}
.header {
	position: fixed;
	background: #fff;
	height: 50px;
	top: v-bind(topHeight);
	width: 100%;
	padding-left: calc(2.8vw + 20px);
	padding-right: 2.8vh;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: space-between;
	z-index: 999;
}
:deep(.uicon-arrow-left) {
	position: absolute;
	left: 2.8vw;
	line-height: 50px !important;
}
:deep(.uicon-arrow-left) {
	color: #171717 !important;
	font-size: 32rpx !important;
	font-weight: 900 !important;
}
:deep(.u-search__action--active) {
	width: 51px;
	height: 29px;
	background: linear-gradient(89deg, #00c4fe 0%, #4e6fff 100%);
	border-radius: 15px 15px 15px 15px;
	position: absolute;
	line-height: 29px;
	right: 2.8vh;
	color: #fff;
	text-align: center;
	font-size: 12px;
	margin: 2px 0;
}
:deep(.u-search__content__close) {
	position: absolute !important;
	right: calc(2.8vh + 56px) !important;
	color: #666 !important;
}
.empty-box {
	padding-top: 354rpx;
	display: flex;
	align-items: center;
	flex-direction: column;
	justify-content: center;
	.empty-title {
		font-size: 20px;
		color: #666;
		margin-top: 38px;
	}
	.empty-tip {
		font-size: 14px;
		color: #999;
		margin-top: 5px;
	}
}
.no-more {
	width: 100%;
	height: 25px;
	line-height: 25px;
	text-align: center;
	color: #999;
	margin-top: 20px;
	font-size: 14px;
}
</style>
